import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common'
import { Reflector } from '@nestjs/core'
import { UserRole } from '@prisma/client'
import { AuthUser } from '../interfaces/jwt-payload.interface'

/**
 * 角色守卫
 * 用于检查用户是否具有访问特定资源的角色权限
 */
@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private readonly reflector: Reflector) {}

  /**
   * 判断是否可以激活路由
   * @param context 执行上下文
   * @returns 是否可以访问
   */
  canActivate(context: ExecutionContext): boolean {
    // 获取路由所需的角色
    const requiredRoles = this.reflector.getAllAndOverride<UserRole[]>('roles', [
      context.getHandler(),
      context.getClass()
    ])

    // 如果没有设置角色要求，则允许访问
    if (!requiredRoles || requiredRoles.length === 0) {
      return true
    }

    // 获取当前用户信息
    const request = context.switchToHttp().getRequest()
    const user: AuthUser = request.user

    // 检查用户是否存在
    if (!user) {
      throw new ForbiddenException('用户信息不存在')
    }

    // 检查用户角色是否满足要求
    const hasRole = requiredRoles.includes(user.role)

    if (!hasRole) {
      throw new ForbiddenException('权限不足，无法访问此资源')
    }

    return true
  }
}
